/*!
 * Copyright (c) 2010 Jacob Essex
 *
 * Dual licenced under MIT or GPL 3 licneces
 * 
 * See the GPL3 or MIT files in the main directory for details
 */

require.def('db/tags', ['log/db', 'db'],
function(Log, Db){
    function Tag(db, tbl, id){
        this.__proto__ = new Db.Row(this,db, tbl, id);
        this.Name = '';
        this.Count = 0;
    }
    return {

        TagsDb: function(db){
            var tbl = new Db.TableDef('Tags', ['Name', 'Count']);

            this.destroy = function(tx, funcs){
                var execSql = function(tx){
                    tx.executeSql(
                        'DROP TABLE IF EXISTS ' + tbl.name,
                        [],
                        funcs && funcs.success ? function(tx,rs){funcs.success(tx);} : function(){},
                        funcs && funcs.error ? function(tx, e){funcs.error(e.message);} : function(){}
                    );
                };
                if ( tx ){
                    execSql(tx);
                }else{
                    db.transaction(execSql);
                }
            };

            this.create = function(tx, funcs){
                var execSql = function(tx){
                    var sql = 'CREATE TABLE IF NOT EXISTS ' + tbl.name + ' ('
                            + 'Id integer, Name varchar(126), Count integer,' 
                            + 'PRIMARY KEY(Id)'
                            + ')';
                    tx.executeSql(
                        sql,
                        [],
                        funcs && funcs.success ? function(tx,rs){funcs.success(tx);} : function(){},
                        funcs && funcs.error ? function(tx, e){funcs.error(e.message);} : function(){}
                    );
                };
                if ( tx ){
                    execSql(tx);
                }else{
                    db.transaction(execSql);
                }
            }

            this.createTag = function(tx, funcs){
                var s = new Tag(db, tbl, Db.ROW_NOT_CREATED);
                Log.info('Created new tag');
                funcs.success && funcs.success(tx, s);
            }

            this.count = function(tx, funcs){
                var execSql = function(tx){
                    Db.site.count(tx, tbl.name, ['Name'], [name], funcs);
                };
                if ( tx ){
                    execSql(tx);
                }else{
                    db.transaction(execSql);
                }
            }
            this.exists = function(tx, name, funcs){
                var execSql = function(tx){
                    tx.executeSql(
                        'SELECT * FROM ' + tbl.name + ' WHERE Name=? LIMIT 1',
                        [name],
                        function(tx, rs){
                            if ( rs.rows.length === 0 ){
                                Log.info(name + ' doesn\'t exist');
                                funcs.no && funcs.no(tx);
                            }else{
                                Log.info(name + ' exist');
                                funcs.yes && funcs.yes(tx) 
                            }
                        },
                        function(tx, err){ funcs.error && funcs.error(err.message) }
                    ); 
                };
                if ( tx ){
                    execSql(tx);
                }else{
                    db.transaction(execSql);
                }
            }

            this.getTags = function(tx, funcs){
                if ( funcs === undefined ){
                    return;
                }
                var execSql = function(tx){
                    var sql = 'SELECT * FROM ' + tbl.name 
                    tx.executeSql(
                            sql,
                            [],
                            function(tx, rs){
                                var items = [];
                                for ( var i = 0; i < rs.rows.length; i++ ){
                                    var row = rs.rows.item(i);
                                    var id = row['Id'];
                                    var obj = new Tag(db, tbl, id); 
                                    tbl.columns.forEach(function(k){ obj[k] = row[k]; }); //transfer properties
                                    items.push(obj);
                                }
                                funcs.success && funcs.success(tx, items);
                            },
                            function(tx, err){
                                funcs.error && funcs.error(err.message);
                            }
                    );
                };
                if ( tx ){
                    execSql(tx);
                }else{
                    db.transaction(execSql);
                }
            }

            this.getByTagName = function(tx, tag, funcs){
                var execSql = function(tx){
                    if ( funcs === undefined ){
                        return;
                    }

                    tx.executeSql(
                        'SELECT * FROM '+tbl.name+ ' WHERE Name=?',
                        [tag],
                        function(tx, rs){
                            if ( rs.rows.length == 0 ){
                                funcs.notFound && funcs.notFound();
                            }else if ( rs.rows.length > 1 ){
                                funcs.error && funcs.error('Unexpected number of results. Expceted 1 got '+rs.rows.length);
                            }else{
                                var row = rs.rows.item(0); //there should only be one
                                var id = row['Id'];
                                Log.info('Found with Id ' + id);
                                var obj = new Tag(db, tbl, id);
                                tbl.columns.forEach(function(k){ obj[k] = row[k]; }); //transfer properties
                                funcs.success && funcs.success(tx, obj);
                            }
                        },
                        function(tx, er){
                            funcs.error && funcs.error(er.message);
                        }
                    );
                };
                if ( tx ){
                    execSql(tx);
                }else{
                    db.transaction(execSql);
                }
            }
        }
    }
});
